package com.danbay.cloud.common.service;

import com.danbay.cloud.common.api.dto.Base64ImgDto;
import com.danbay.cloud.common.api.dto.CodeValidateDto;
import com.danbay.cloud.common.api.dto.VerifyCodeDto;
import com.danbay.cloud.common.api.service.IVerifyCodeService;
import com.danbay.cloud.common.verifycode.VerifyCodeGenerator;
import com.danbay.framework.exception.BusinessException;
import com.danbay.framework.redis.RedisClient;
import com.danbay.framework.utils.BeanValidator;
import com.danbay.framework.utils.RandomUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * @author SJG
 *         2018/1/12.
 */
@Service
@Slf4j
public class VerifyCodeService implements IVerifyCodeService {

    private static final String VERIFY_CODE_UUID = "verify_code_";

    @Autowired
    private RedisClient redisClient;

    /**
     * 生成base64验证码图片
     *
     * @param imgInfo 生成图片的信息
     * @return base64验证码图片
     */
    @Override
    public VerifyCodeDto genBase64Img(Base64ImgDto imgInfo) throws BusinessException {
        BeanValidator.valid(imgInfo);

        //生成验证码字符
        String code = VerifyCodeGenerator.generateVerifyCode(4);
        log.info("用户:{}请求取得验证码:{}", imgInfo.getUserName(), code);
        try {
            //生成验证码base64字符串
            String base64Img = VerifyCodeGenerator.genBase64VerifyCode(imgInfo.getWidth(), imgInfo.getHeight(), code);
            String uuid = RandomUtils.randomUUID();
            //缓存验证码字符
            redisClient.set(VERIFY_CODE_UUID + uuid, code, imgInfo.getExpire());
            return VerifyCodeDto.builder().id(uuid).base64Img(base64Img).build();
        } catch (IOException e) {
            throw new BusinessException("生成base64验证码图片失败", e);
        }
    }

    /**
     * 校验用户输入的验证码是否正确
     *
     * @param codeValidate 待验证的验证码信息
     * @return 是否正确
     */
    @Override
    public boolean validate(CodeValidateDto codeValidate) throws BusinessException {
        BeanValidator.valid(codeValidate);
        boolean valid = false;

        String key = VERIFY_CODE_UUID + codeValidate.getId();
        if (redisClient.hasKey(key)) {
            String code = redisClient.get(key);
            valid = codeValidate.getCode().equalsIgnoreCase(code);
        }
        log.info("用户:{}请求校验id:{}验证码:{}结果:{}", codeValidate.getUserName(), codeValidate.getId(), codeValidate.getCode(), valid);
        return valid;
    }

}
